﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameEntities;
using GameCommon;
using Game;
using Engine.UISystem;
using Engine.MapSystem;
using Engine.EntitySystem;
using Engine;
using Engine.PhysicsSystem;

namespace Arcanea.MMORPGClient
{
    class SetupProvider
    {
        #region Singleton

        private static SetupProvider singleton;
        public static SetupProvider Singleton
        {
            get
            {
                if (singleton == null)
                    singleton = new SetupProvider();
                return singleton;
            }
        }
        private SetupProvider()
        {
        }

        #endregion

        private EControl window = null;

        public void SetMusic(GameMap.GameTypes gameType)
        {
            switch (gameType)
            {
                case GameMap.GameTypes.MMORPGPlayerSelection:
                case GameMap.GameTypes.MMORPGPlayerLogin:
                    GameMusic.MusicPlay("Sounds\\Music\\MMORPGSelection.ogg", true);
                    break;
            }
        }

        public MMORPGGameWindow CreateGameWindow(GameMap.GameTypes gameType)
        {
            switch (gameType)
            {
                case GameMap.GameTypes.MMORPGPlayerLogin:
                case GameMap.GameTypes.MMORPGPlayerSelection:
                    return new MMORPGPlayerSelectionGameWindow();
                case GameMap.GameTypes.MMORPGPlay:
                    return new MMORPGPlayGameWindow();
                case GameMap.GameTypes.MMORPGPlayerCreation:
                    return new MMORPGPlayerCreationGameWindow();
                case GameMap.GameTypes.MMORPGStory:
                    return new MMORPGStoryGameWindow();
            }
            return null;
        }

        public void SetUI(GameMap.GameTypes gameType)
        {
            if(window != null)
                window.SetShouldDetach();
            switch (gameType)
            {
                case GameMap.GameTypes.MMORPGPlayerLogin:
                    window = UILoad("Gui\\MMORPGLoggingUI.gui");
                    ((EButton)window.Controls["EnterButton"]).Click += new EButton.ClickDelegate(Logging_Click);
                    break;
                case GameMap.GameTypes.MMORPGPlayerSelection:
                    window = UILoad("Gui\\MMORPGSelection.gui");
                    ((EButton)window.Controls["ChooseButton"]).Click += new EButton.ClickDelegate(Choose_Click);
                    ((EButton)window.Controls["NewButton"]).Click += new EButton.ClickDelegate(New_Click);
                    break;
            }
        }

        public void LoadMap(GameMap.GameTypes gameType)
        {
            switch (gameType)
            {
                case GameMap.GameTypes.MMORPGPlayerLogin:
                case GameMap.GameTypes.MMORPGPlayerSelection:
                    MapLoad("Maps\\MMORPGPlayerSelectionGameWindowMap\\Map.map");
                    break;
            }
        }

        #region private methods

        private EControl UILoad(string UIName)
        {
            EControl ui = ControlDeclarationManager.Instance.CreateControl(UIName);
            if (ui != null)
            {
                ScreenControlManager.Instance.Controls.Add(ui);
            }
            return ui;
        }

        private bool MapLoad(string fileName)
        {
            EControl mapLoadingWindow = UILoad("Gui\\ProgramLoadingWindow.gui");
            
            ArcaneaEngineApp.Instance.RenderScene();

            //delete all GameWindow's
            DeleteAllGameWindows();

            MapSystemWorld.MapDestroy();

            WorldType needWorldType = GetWorldType();

            if (World.Instance == null || World.Instance.Type != needWorldType)
            {
                if (needWorldType == null)
                {
                    if (mapLoadingWindow != null)
                        mapLoadingWindow.SetShouldDetach();
                    return false;
                }

                if (!EntitySystemWorld.Instance.WorldCreate(WorldSimulationType.Single,
                    needWorldType))
                {
                    Log.Fatal("EntitySystemWorld.Instance.WorldCreate failed.");
                }
            }

            if (!MapSystemWorld.MapLoad(fileName))
            {
                if (mapLoadingWindow != null)
                    mapLoadingWindow.SetShouldDetach();
                return false;
            }

            //Simulate physics for 5 seconds. That the physics has fallen asleep.
            if (PhysicsWorld.Instance != null)
            {
                //inform entities about this simulation
                foreach (Entity entity in Map.Instance.Children)
                {
                    Dynamic dynamic = entity as Dynamic;
                    if (dynamic != null)
                        dynamic.SuspendPhysicsDuringMapLoading(true);
                }

                PhysicsWorld.Instance.EnableCollisionEvents = false;

                const float seconds = 5;

                for (float time = 0; time < seconds; time += Entity.TickDelta)
                {
                    PhysicsWorld.Instance.Simulate(Entity.TickDelta);

                    //WaterPlane specific
                    foreach (WaterPlane waterPlane in WaterPlane.Instances)
                        waterPlane.TickPhysicsInfluence(false);
                }

                PhysicsWorld.Instance.EnableCollisionEvents = true;

                //inform entities about this simulation
                foreach (Entity entity in Map.Instance.Children)
                {
                    Dynamic dynamic = entity as Dynamic;
                    if (dynamic != null)
                        dynamic.SuspendPhysicsDuringMapLoading(false);
                }
            }

            //Error
            foreach (EControl control in ScreenControlManager.Instance.Controls)
            {
                if (control is MessageBoxWindow)
                    return false;
            }

            CreateGameWindowForMap();

            EntitySystemWorld.Instance.ResetExecutedTime();

            return true;
        }

        private void DeleteAllGameWindows()
        {
        ttt:
            foreach (EControl control in ScreenControlManager.Instance.Controls)
            {
                if (control is GameWindow)
                {
                    ScreenControlManager.Instance.Controls.Remove(control);
                    goto ttt;
                }
            }
        }

        private WorldType GetWorldType()
        {
            List<EntityType> list = EntityTypes.Instance.GetTypesBasedOnClass(
                EntityTypes.Instance.GetClassInfoByEntityClassName("World"));

            for (int n = 0; n < list.Count; n++)
            {
                if (list[n].ManualCreated)
                {
                    list.RemoveAt(n);
                    n--;
                }
            }

            if (list.Count == 0)
            {
                Log.Error("World type not defined.");
                return null;
            }
            if (list.Count != 1)
            {
                Log.Error("Only one instance of World type is supported.");
                return null;
            }
            return (WorldType)list[0];
        }

        private void CreateGameWindowForMap()
        {
            ScreenControlManager.Instance.Controls.Clear();

            MMORPGGameWindow gameWindow = null;

            //Create specific game window
            if (GameMap.Instance != null)
                gameWindow = SetupProvider.Singleton.CreateGameWindow(GameMap.Instance.GameType);

            //if (gameWindow == null)
            //    gameWindow = new ActionGameWindow();

            ScreenControlManager.Instance.Controls.Add(gameWindow);
        }

        #endregion

        #region UI Textbox

        private void Logging_Click(EButton sender)
        {
            string login = ((EEditBox)window.Controls["LoginEditBox"]).Text;
            string password = ((EEditBox)window.Controls["PasswordEditBox"]).Text;

            //Verification
            if(login == "alphamax" && password == "alphamax")
            {
                SetUI(GameMap.GameTypes.MMORPGPlayerSelection);
                EComboBox cmb = ((EComboBox)window.Controls["ComboboxPerso"]);
                cmb.Items.Add("Personage 1");
                cmb.Items.Add("Personage 2");
                cmb.Items.Add("Personage 3");
                if (cmb.Items.Count != 0)
                {
                    cmb.Visible = true;
                    ((EButton)window.Controls["ChooseButton"]).Visible = true;
                    cmb.SelectedIndex = 0;
                }
                else
                {
                    cmb.Visible = false;
                    ((EButton)window.Controls["ChooseButton"]).Visible = false;
                }
                //Peuple le choix des joueurs
            }
        }

        private void Choose_Click(EButton sender)
        {
            //On entre dans le monde
            ArcaneaEngineApp.ActualGameType = GameMap.GameTypes.MMORPGPlay;
        }

        private void New_Click(EButton sender)
        {
            //Phase de création
            ArcaneaEngineApp.ActualGameType = GameMap.GameTypes.MMORPGPlayerCreation;
        }

        #endregion
    }
}
